<?php

/**
 * @author liyi
 * @DateTime 2018.12.27
 */

namespace Plangame\Controller;
use Common\Controller\ApiController;
use Think\Model;
use Think\Log;

class IndexController extends ApiController {
    
    const GAME_TYPE = 'Planegame';  // 游戏类型

   // const USER_UID = "plane:user:%s:type:%s:qid:%s";  // 用户主键

    const USER_INVITE ="plane:invite:type:%s"; // 用户每日任务邀请类型记录键

    const IS_REWARD_UID ='plane:is:reward:uid:%s'; // 是否领取每日任务

    const QID_UID ='plane:user:%s:type:%s:qid:%s'; // 用户解锁邀请

    const PLANE_SESSION = 'plane:';  // 用户sessionid

    const PLANE_SHARE = "plane:share";  // 普通分享到群次数

    const PLANE_INVITE = "plane:invite"; // 邀请用户次数

    const RANK_LIST = "plane:rankList"; // 排汗榜列表(缓存)

    const PLANE_PLAY = "plane:play"; // 游戏次数(本游戏没有次数)

    const PWZW_UPGRADE = "plane:upgrade"; // 用户升级次数

    const PLANE_VIDEO = 'plane:video';  // 看完视频的用户

    const USER_SHARE = 'plane:user:%s:type:%s';  // 点击分享按钮的次数

    public function __construct()
    {
        parent::__construct();

        $uid = $this->isLogin(self::PLANE_SESSION);
        $id = I('id','','int');
        if(empty($uid)) {
            $uid = $id;
            //$uid = $this->isParamLogin($id);
        }
        if (!$uid) {
            $this->response(1,'请先登录');
        }
        $this->uid = $uid;
    }

    // 排行榜
    public function rankingList()
    {
        $redis = REDIS('activity');
        $redis->select(2);
        $hash_key = self::RANK_LIST;    //排行榜缓存键

        $ret = $this->getRankList($hash_key,true,2,'score');

        if(empty($ret)) {
            //$where['nickname'] = array('neq','');
            //$where['avatar'] = array('neq','');
            $where['score'] = array('neq',0,'AND');
            $where['black_list'] = 1;
            $ret = M('users')->field('id,nickname,avatar,score,grade')->where($where)->order('score desc,id asc')->limit(200)->select();
            foreach($ret as $k=>$v) {
                if(!empty($v['nickname']) && !empty($v['avatar'])){
                    $id = $v['id'];
                    $flag = $redis->hSet($hash_key,$id, json_encode($v));
                }
            }
        }

        $this->response(0, "OK",array('randList'=>$ret));
    }

    // 游戏复活
    public function revives()
    {
        $uid = $this->uid;
        $revive = I('revive',0,'int'); // 复活金币

        $res = $this->revive($uid,$revive,3);
        if(!$res) {
            $this->response(1, "操作失败");
        }
        $this->response(0, "操作成功");
    }

    // 解密数据  //这里逻辑处理
    public function cryptData()
    {
        $uid = $this->uid;
        $info = C(self::GAME_TYPE);
        $appid = $info['APPID'];
        $sessionKey = I('sessionKey','','string'); // sessionKey
        $encryptedData = I('encryptedData','','string'); // 加密数据
        $iv = I('iv','','string');
        $type = I('type',0,'int');  // 1:缓存当天有效 2：每局游戏有效

        $pc = new \Org\Util\WXBizDataCrypt($appid, $sessionKey);
        $errCode = $pc->decryptData($encryptedData, $iv, $data);

        $data = $data ? json_decode($data, true) : '';
        $openGId = isset($data['openGId']) ? $data['openGId'] : 0;

        if ( $errCode == 0 ) {  // 解密成功

            $redis = REDIS('activity');
            $evening = date('Y-m-d 23:59:59'); //每日23点59分
            $userKey = sprintf(self::QID_UID,$uid,$type,$openGId);  //用户主键分享到群
            $shareKey = $redis->get($userKey);

            Log::write('解密test:'.$shareKey.'|成功uid:'.$uid.'|操作类型：'.$type.'|解密操作值：'.$openGId,'SUCCESS');

            if( $type == 2 && $shareKey == 1 ) {
                $this->response(2,'每局游戏同一群只能分享一次');
            }

            if( $type == 1 && $shareKey == 1  ) {
                $this->response(3,'每天同一群只能分享一次');
            }

            $redis->set($userKey,1);  // 标记
            $redis->exprieAt($userKey,strtotime(date('Y-m-d 23:59:59'))); // 每日23点59分过期

            $this->countLog('planes',self::PLANE_SHARE);  // 记录分享次数日志
            $result = $data ? json_decode($data, true) : '';
            $this->response(0, "成功解密",$result);
        }
        Log::write('解密失败:'.$errCode.'|失败uid:'.$uid.'|操作类型：'.$type.'|操作值：'.$data,'ERROR');
        $this->response(1, "解密失败");
    }

    //邀请记录
    public function inviteRecord()
    {
        $uid = I('id',0,'int'); // 邀请人
        $invite_uid = I('invite_uid',0,'int');// 被邀请人
        $time = date('Y-m-d');
        $type = I('type',1,'int'); //1:每日邀请 2：解锁武器邀请 3:火力加成邀请 4:最强战机
        $best = I('best',0,'int');

        // 最强战机
        if($type == 10){
            $niu['uid'] = $uid;
            $niu['type'] = 10;
            $user = M('invite_log')->where($niu)->find();
            if (!empty($user))
            {
                $this->response(3, "已被邀请过");
            }else{
                $count = M('invite_log')->where($niu)->count();
                if($count > 7){
                    $map['id'] = $uid;
                    $userInfo = M('users')->field('have_skin')->where($map)->find();
                    $haveSkin = $userInfo['have_skin'];
                    $skinArr = explode(',', $haveSkin);
                    if(in_array(10,$skinArr)) {
                        $this->response(9, "最强战机已领取！");
                    }else{
                        $this->response(8, "最强战机已达到，请领取！");
                    }
                }else{
                    $niu['invite_uid'] = $invite_uid;
                    $niu['create_time'] = date('Y-m-d H:i:s');
                    $ret = M('invite_log')->add($niu);
                    if(empty($ret)) {
                        $this->response(1, "操作失败");
                    }else{
                        $this->response(0, "操作成功");
                    }
                }
            }
        }

        $map['uid'] = $uid;
        $map['type'] = array('neq',4);
        $map['left(create_time,10)'] = $time;
        $user = M('invite_log')->where($map)->find();
        
        if (!empty($user))
        {
            $this->response(3, "已被邀请过"); 
        }

        if( $uid != $invite_uid ) {  //如果不是自己邀请自己
            // 转发邀请记录
            $typeForward = array("101", "102", "103");
            if (in_array($type, $typeForward)) {
                $type_table = 'plan';   // redis表
                $this->getForward($uid, $invite_uid, $type_table, $type);
            }

            $data['uid'] = $uid;
            $data['invite_uid'] = $invite_uid;
            $data['create_time'] = $type == 3 ? date('Y-m-d H:i:s') : $time;
            $data['type'] = $type;

            $ret = M('invite_log')->add($data);
            if(empty($ret)) {
                $this->response(1, "操作失败");
            }
            $this->countLog('planes',self::PLANE_INVITE);  // 记录邀请次数日志              
        }else{
            $this->response(1, "自己不能邀请自己");
        }
   
        $this->response(0, "操作成功");
    }

    //获取邀请列表 int $type 1:每日邀请 2：解锁武器邀请 10:最强战机邀请
    public function getInviteList($type) {
        if(!$type) return false;
        $uid = $this->uid;

        $userInfo = array();
        $number = 0; //邀请人数

        // $userKey = sprintf(self::USER_UID,$uid);  // 用户主键
        // $inviteKey = sprintf(self::USER_INVITE,$type); // 邀请类型
        // $redis = REDIS('activity');
        // $lottery = $redis->hGet($userKey,$inviteKey);
        // $userInfo = json_decode($lottery,true);
        // $number = intval(count($userInfo));

        $map['invite_uid'] = $uid;
        $map['type'] = $type;
        $map['left(create_time,10)'] = date('Y-m-d');

        $list = M('invite_log')->field('uid,create_time')->where($map)->order('id asc')->select();
      
        if(!empty($list)) {
            $number = intval(count($list));
            $uidArr = array_column($list,'uid');
            $timeArr = array_column($list,'create_time','uid');
            $uidStr = implode(',', $uidArr);
            $where['id'] = array('in',$uidStr);
            $userInfo = M('users')->field('id,nickname,avatar')->where($where)->select();
            foreach($userInfo as $k=>$v) {
                $userInfo[$k]['create_time'] = strtotime($timeArr[$v['id']]);
            }
        }
        
        $user = !empty($userInfo) ? $userInfo : array();
        return array('userInfo'=>$user,'number'=>$number);
    }

    // 每日任务列表
    public function everyDayTask() {
        $uid = $this->uid;
        $data = array();
        $type = 1; // 每日任务邀请
        $list = $this->getInviteList($type);

        $isAeward = sprintf(self::IS_REWARD_UID,$uid);
        $redis = REDIS('activity');
        $res = $redis->get($isAeward);

        if(empty($res)) { 
            $map['uid'] = $uid;
            $map['status'] = 1;
            $map['reward_type'] = 1;  // 每日邀请任务
            $map['create_time'] = date('Y-m-d');
            $ret = M('users_draw_log')->where($map)->find();
        }
        
        $list['status'] = !empty($ret) ? 1 : 2 ; // 1: 已领取 2：未领取
        
        $this->response(0, "ok",$list);
    }

    // 领取每日任务
    public function getTask() {
        $uid = $this->uid;
        $gold = I('gold',0,'int');  // 钻石
        $bomb = I('bomb',0,'int');  // 炸弹
        $pid = I('pid',1,'int');  // 奖品编号
        $name = I('name','豪华大礼包','string'); // 奖品名称
        $time = date('Y-m-d');
        if(empty($gold)) {
            $this->response(1, "金币不能为空");
        }

        $isAeward = sprintf(self::IS_REWARD_UID,$uid);
        $redis = REDIS('activity');
        $isStatus = $redis->get($isAeward);
        if($isStatus > 0 ) {
            $this->response(2, "今日以领取奖励");
        }
       
        $map['id'] = $uid;
        $param['bomb'] = array('exp',"bomb + $bomb");
        $param['gold'] = array('exp',"gold + $gold");
        $res = M('users')->where($map)->save($param); // 领取金币和炸弹

        $data = array('uid'=>$uid,'reward_type'=>1,'reward_grid'=>$pid,'reward_name'=>$name,'create_time'=>$time);
        $ret = M('users_draw_log')->add($data);
        if(!$ret) {
            $this->response(1, "操作失败");
        }
    
        $redis->set($isAeward,1);
        $redis->exprieAt($isAeward,strtotime(date('Y-m-d 23:59:59'))); // 每日23点59分过期

        $this->response(0, "操作成功");
    }

   
    // 道具列表
    public function propList() {
        $uid = isset($this->uid)?$this->uid:I('post.id');
        $map['id'] = $uid;
        $userInfo = M('users')->field('skin,have_skin')->where($map)->find();
        $haveSkin = explode(',',$userInfo['have_skin']);
        $propList = C('USER_ATTR');
        foreach($propList as $k=>$v) {
            $propList[$k]['status'] = in_array($v['id'], $haveSkin) ? 1 : 2; // 0：未满足条件 1:已领取 2：未领取
        }
        $role = $userInfo['skin'];

        $type = 2;  // 解锁武器邀请
        $inviteList = $this->getInviteList($type);

        $data = array('propList'=>$propList,'role'=>$role,'inviteList'=>$inviteList);

        $this->response(0,"OK",$data);
    }

    // 道具列表 最强战机邀请列表
    public function propList2() {
        $uid = isset($this->uid)?$this->uid:I('post.id');
        $map['id'] = $uid;
        $userInfo = M('users')->field('skin,have_skin')->where($map)->find();
        $haveSkin = explode(',',$userInfo['have_skin']);
        $propList = C('USER_ATTR');
        foreach($propList as $k=>$v) {
            $propList[$k]['status'] = in_array($v['id'], $haveSkin) ? 1 : 2; // 0：未满足条件 1:已领取 2：未领取
        }
        $role = $userInfo['skin'];

        $type = 10;  // 最强战机邀请
        $inviteList = $this->getInviteList($type);

        $data = array('inviteList'=>$inviteList);

        $this->response(0,"OK",$data);
    }

    // 火力加成列表
    public function fireList() {
        $type = 3;  // 火力加成类型
        $inviteList = $this->getInviteList($type);
        $this->response(0,"OK",$inviteList);
    }

    //道具解锁
    public function getProp() {
        $uid = $this->uid;
        $gold = I('gold',0,'int');  // 金币
        $propId = I('propid',0,'int'); //道具类型
        $type = I('type',0,'int');  // 1:消耗金币 2：分享邀请解锁

        if(empty($propId)) {
            $this->response(2, "请选道具类型");
        }

        if($type == 1) {
            if(empty($gold)) {
                $this->response(3,"金币不能为空");
            }
            $this->setGold($uid,'dec',1,$gold);  // 消耗钻石
        }else{

            $maps['invite_uid'] = $uid;
            if($propId==10){
                $maps['type'] = $propId;
                $maps['left(create_time,10)'] = date('Y-m-d');
                $total = M('invite_log')->where($maps)->count('id');
                if($total < 8) {
                    $this->response(4,'邀请人数不足8人');
                }
            }else{
                $maps['type'] = $type;
                $maps['left(create_time,10)'] = date('Y-m-d');
                $total = M('invite_log')->where($maps)->count('id');
                if($total < 3) {
                    $this->response(4,'今日邀请人数不足3人');
                }
            }

        }

        $map['id'] = $uid;
        $userInfo = M('users')->field('have_skin,weapons')->where($map)->find();
        $haveSkin = $userInfo['have_skin'];
        $skinArr = explode(',', $haveSkin);

        if(in_array($propId,$skinArr)) {
            $this->response(3, "恭喜！已经具备该武器了");
        }
        
        $param['have_skin'] = $userInfo['have_skin'].','.$propId;
        $weapons = json_decode($userInfo['weapons'],true);

        $arsenal = array($propId=>array('skin'=>$propId,'attack_lv'=>1,'speed_lv'=>1,'blood_lv'=>1,'status'=>1));

        $arr = $weapons + $arsenal;
        $param['weapons'] = json_encode($arr);
        $ret = M('users')->where($map)->save($param);
        if(empty($ret)) {
            $this->response(1, "操作失败");
        }
        $this->response(0,"操作成功");
    }

    // 武器升级列表
    public function getSurvey(){
        $uid = $this->uid;
        $map['id'] = $uid;
        $field = 'id,gold,skin,weapons';
        $userInfo = M('users')->field($field)->where($map)->find();
        $userInfo['weapons'] = json_decode($userInfo['weapons'],true);
        $this->response(0,"OK",$userInfo);
    }

    // 武器升级
    public function upgradeUserAttr() {
        $uid = $this->uid;
        $propid = I('propid','0','int'); //道具编号
        $type = I('type',0,'int'); // 1:升级火力 2：升级射速 3：升级血量 4:满50级升级
        $gold = I('gold',0,'int');

        if( $type != 4 ) {
            if(empty($gold)) {
                $this->response(2,'金币不能为空');
            }
        }

        if(empty($propid)) {
            $this->response(3,'请选择武器');
        }

        $propLevel = array(1=>'attack_lv',2=>'speed_lv',3=>'blood_lv',4=>'status');
        $attrLv = $propLevel[$type];

        $map['id'] = $uid;
        if( $type != 4) {
            $userInfo = M('users')->field('gold')->where($map)->find();
            if( $gold > $userInfo['gold']) {
                $this->response(5,'金币不足');
            }
            $param['gold'] = array('exp',"gold - $gold");

            $res = M('users')->where($map)->save($param);  // 消耗金币
            if(empty($res)) {
                $this->response(1,'操作失败');
            }
            //$this->setGold($uid,'dec',1,$gold);  // 消耗金币
        }

        $userInfo = M('users')->field('id,weapons')->where($map)->find();

        $weapons = json_decode($userInfo['weapons'],true);

        if($type == 4) {
            if($weapons[$propid]['attack_lv'] < 10 || $weapons[$propid]['speed_lv'] < 10 || $weapons[$propid]['blood_lv'] < 10) {
                $this->response(4,'未满足升级条件');
            }
        }

        $weapons[$propid][$attrLv] += 1;  // 升级对应的武器属性

        $data['weapons'] = json_encode($weapons);
        
        $contion['id'] = $uid; 
        $ret = M('users')->where($contion)->save($data);
        
        if(empty($ret)) {
            $this->response(1, "操作失败");
        }
        $this->countLog('planes',self::PWZW_UPGRADE);  // 升级成功次数
        $this->response(0,"操作成功");
    }

    // 记录用户点击分享按钮的次数
    public function setShare() {
        $uid = $this->uid;
        $type = I('type',1,'int');  // 1:分享 2：看完视频 3:分享领取奖励成功
        $redis = REDIS('activity');
        $userKey = sprintf(self::USER_SHARE,$uid,$type);  //用户主键分享到群
        if($type == 2) {
            $this->countLog('planes',self::PLANE_VIDEO);  // 记录看完视频的次数
        }
        if($type == 1) {
            $this->countLog('planes','plane:share');  // 分享次数
        }
        if($type == 1 || $type == 3) {
            $redis->incrBy($userKey,1);
            $redis->exprieAt($userKey,strtotime(date('Y-m-d 23:59:59'))); // 每日23点59分过期
        }
        $this->response(0,'ok');
    }

    // 记录游戏成绩
    public function addGameResult()
    {
        $uid = $this->uid;  // 用户ID
        $score = I('score',0,'string'); // 积分
        $gold = I('gold',0,'string'); //金币
        $bomb = I('bomb',0,'int'); // 炸弹

        $grade = I('grade',0,'string');  // 积分等级

        $map['id'] = $uid;
        $users = M('users')->where($map)->find();

        if(empty($score)) {
            $this->response(2, "用户积分不能为空");
        }

        $redis = REDIS('activity');
        $redis->select(2);
        $hashKey = self::RANK_LIST; //排行榜列表
        $rank_list = $redis->hGetAll($hashKey);
        if($rank_list){
            $data = array('id'=>$users['id'],'score'=>$score,'userid'=>$users['userid'],'nickname'=>$users['nickname'],'avatar'=>$users['avatar']);

            $this->setRankList($hashKey,2,$data,$users['id'],'score',$score);// 记录缓存成绩
        }

        if( $score > $users['score'] ) {   // 游戏成绩大于当前最好成绩
            $params['score'] = $score;     
        }
        $params['bomb'] = $bomb;
        $params['gold'] = $gold;
        $params['grade'] = $grade;
        $status = M('users')->where($map)->save($params);
        if(empty($status)) {
            $this->response(3, "跟新用户最好成绩失败");
        }
      
        // $contion['uid'] = $uid;
        // $rets = M('play_log')->where($contion)->find();

        // if(!empty($rets)) {
           
        //     $param['update_time'] = date("Y-m-d H:i:s");
        //     $param['score'] = $score;
        //     $result = M('play_log')->where($contion)->save($param);
        //     if(empty($result)) {
        //         $this->response(1, "操作失败");
        //     }
        //     $this->response(0, "操作成功"); 
        // }

        // $data = array('uid'=>$uid,'score'=>$score,'create_time'=>date("Y-m-d H:i:s"));
        // $res = M('play_log')->add($data);
        // if(empty($res)) {
        //     $this->response(1, "操作失败");
        // }
        
        // 每局群分享限制
        // $redis = REDIS('activity');    
        // $userKey = sprintf(self::QID_UID,$uid,2,'*');  //用户主键分享到群
        // $delKey = $redis->keys($userKey);
        // $redis->del($delKey);

        $this->countLog('planes',self::PLANE_PLAY);  // 记录邀请次数日志   

        $this->response(0, "操作成功"); 
    }

    // 获取session_key
    public function getSessionKey() {
        $gameType = self::GAME_TYPE;
        $code = I('code','','string');
        if(!$code) {
            $this->response(2,'code不能为空');
        }
        $info = $this->wxAuthor($gameType,$code);
        if(empty($info)) {
            $this->response(1,"操作失败"); 
        }

        $this->response(0,"OK",array('session_key'=>$info['session_key']));
    }

    // 设置金币
    public function setGolds()
    {
        $uid = $this->uid;
        $gold = I('gold','0','int');
        $type = I('type',1,'int');
        if($type == 1) {
            $this->setGold($uid,'inc',1,$gold);  // 领取金币
        }else {
            $this->setGold($uid,'dec',1,$gold);
        }
        
        $this->response(0,'操作成功');
    }

    // 用户登录游戏跟新数据
    public function upgrade() {
        $uid = $this->uid;
        $gold = I('gold',0,'int');  //金币
        $bomb = I('bomb',0,'int');  // 炸弹
        $weapons = $_POST['weapons'];

        $map['id'] = $uid;

        $userInfo = M('users')->field('id,weapons')->where($map)->find();
        $userWeapons = json_decode($userInfo['weapons'],true);  // 数据库武器库记录
        $list = json_decode($weapons,true); // 客户端最新的武器库记录
        foreach($list as $k1=>$v1) {
            foreach($v1 as $k2=>$v2) {
                $newUserWeapons[$k2] = $v2;
            }  
        }

        foreach( $newUserWeapons as $k=>$v) {
            $num = array_sum($newUserWeapons[$k]);  // 计算最新武器升级等级
            $userNum = array_sum($userWeapons[$k]); // 计算数据库武器升级等级
            if($num > $userNum) {
                $userWeapons[$k] = $newUserWeapons[$k];    //  又升级就跟新武器库
            }
        }

        $data['weapons'] = json_encode($userWeapons);
        $data['gold'] = $gold;
        $data['bomb'] = $bomb;
        $ret = M('users')->where($map)->save($data);

        $jsons['errno'] = 0;
        $jsons['msg'] = '操作成功';
        $this->ajaxReturn($jsons); 
    }

    // 获取服务器当前时间
    public function getServerTime(){
        $time = time();
        $this->response(0, "ok",$time);
    }


}